package com.saikali.android_skwissh.charts; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import org.achartengine.ChartFactory; import org.achartengine.chart.BarChart.Type; import org.achartengine.model.CategorySeries; import org.achartengine.model.TimeSeries; import org.achartengine.model.XYMultipleSeriesDataset; import org.achartengine.renderer.DefaultRenderer; import org.achartengine.renderer.SimpleSeriesRenderer; import org.achartengine.renderer.XYMultipleSeriesRenderer; import org.achartengine.renderer.XYSeriesRenderer; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Color; import android.graphics.Paint.Align; import android.graphics.Typeface; import android.preference.PreferenceManager; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.saikali.android_skwissh.objects.SkwisshSensorItem; public class SensorGraphViewBuilder { private int[] colors = new int[] { Color.rgb(127, 174, 0), Color.rgb(234, 162, 40), Color.rgb(213, 56, 59), Color.rgb(78, 165, 181), Color.rgb(127, 174, 0), Color.rgb(234, 162, 40), Color.rgb(213, 56, 59), Color.rgb(78, 165, 181), Color.rgb(127, 174, 0), Color.rgb(234, 162, 40), Color.rgb(213, 56, 59), Color.rgb(78, 165, 181), Color.rgb(127, 174, 0), Color.rgb(234, 162, 40), Color.rgb(213, 56, 59), Color.rgb(78, 165, 181) }; private int fontColor = Color.rgb(77, 77, 77); private int lightFontColor = Color.rgb(170, 170, 170); private int backgroundColor = Color.rgb(242, 242, 242); private String period; private SkwisshSensorItem sensor; private Context context; private int[] margins = new int[] { 20, 80, 30, 40 }; public SensorGraphViewBuilder(Context context, SkwisshSensorItem sensor) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()); this.period = sharedPrefs.getString("default_period", "day"); this.sensor = sensor; this.context = context; } public View createGraphView() { if (this.sensor.getGraphTypeName().equals("pie")) return this.createPieView(); else if (this.sensor.getGraphTypeName().equals("linegraph")) return this.createLineView(); else if (this.sensor.getGraphTypeName().equals("linegraph_stacked")) return this.createLineStackedView(); else if (this.sensor.getGraphTypeName().equals("bargraph")) return this.createBarView(); else if (this.sensor.getGraphTypeName().equals("bargraph_groups")) return this.createBarGroupView(); else if (this.sensor.getGraphTypeName().equals("text")) return this.createTextView(); return null; } private XYMultipleSeriesRenderer getDefaultRenderer() { XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer(); renderer.setApplyBackgroundColor(true); renderer.setInScroll(true); renderer.setAntialiasing(true); renderer.setLabelsTextSize(14); renderer.setLegendTextSize(14); renderer.setPanEnabled(false); renderer.setShowLegend(false); renderer.setShowGrid(true); renderer.setMargins(this.margins); renderer.setFitLegend(true); renderer.setAxesColor(this.fontColor); renderer.setLabelsColor(this.fontColor); renderer.setBackgroundColor(this.backgroundColor); return renderer; } private View createPieView() { // Categories CategorySeries categorySeries = new CategorySeries(this.sensor.getDisplayName()); String[] labels = this.sensor.getLabels().split(";"); String[] values = new String[] {}; try { values = this.sensor.getMeasures().get(0).getValue().split(";"); } catch (IndexOutOfBoundsException ioobe) { return this.createTextView(); } for (int i = 0; i < values.length; i++) { categorySeries.add(labels[i], new Double(values[i])); } // Renderer DefaultRenderer renderer = this.getDefaultRenderer(); for (int color : Arrays.copyOfRange(this.colors, 0, values.length)) { SimpleSeriesRenderer r = new SimpleSeriesRenderer(); r.setColor(color); renderer.addSeriesRenderer(r); } renderer.setPanEnabled(false); renderer.setMargins(new int[] { 0, 0, 0, 0 }); return ChartFactory.getPieChartView(this.context, categorySeries, renderer); } private View createLineView() { // Categories XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); String[] labels = this.sensor.getLabels().split(";"); int nb_values = 0; try { nb_values = this.sensor.getMeasures().get(0).getValue().split(";").length; } catch (IndexOutOfBoundsException ioobe) { return this.createTextView(); } for (int i = 0; i < nb_values; i++) { TimeSeries timeSerie = new TimeSeries(labels[i]); for (int j = 0; j < this.sensor.getMeasures().size(); j++) { Double value = new Double(this.sensor.getMeasures().get(j).getValue().split(";")[i]); Date date = this.sensor.getMeasures().get(j).getTimestamp(); timeSerie.add(date, value); } dataset.addSeries(timeSerie); } // Renderer XYMultipleSeriesRenderer renderer = this.getDefaultRenderer(); for (int color : Arrays.copyOfRange(this.colors, 0, nb_values)) { XYSeriesRenderer r = new XYSeriesRenderer(); r.setColor(color); r.setFillBelowLine(true); r.setFillBelowLine(false); r.setFillPoints(true); r.setLineWidth(2); renderer.addSeriesRenderer(r); } renderer.setShowLegend(true); renderer.setPanEnabled(false, false); renderer.setZoomEnabled(false, false); renderer.setGridColor(this.lightFontColor); renderer.setMarginsColor(this.backgroundColor); renderer.setXLabelsColor(this.fontColor); renderer.setYLabelsColor(0, this.fontColor); renderer.setYLabelsAlign(Align.RIGHT); renderer.setYAxisMin(0); renderer.setXLabels(0); int count = dataset.getSeriesAt(0).getItemCount(); String dateFormat = "HH:mm\nMMM dd"; if (this.period.equals("hour")) { dateFormat = "HH:mm"; } for (int i = 0; i < count; i = i + (count / 5)) { Double d = dataset.getSeriesAt(0).getX(i); Date date = this.sensor.getMeasures().get(i).getTimestamp(); String s = new SimpleDateFormat(dateFormat).format(date); renderer.addXTextLabel(d, s); } this.setYAxisValues(dataset, renderer); return ChartFactory.getTimeChartView(this.context, dataset, renderer, dateFormat); } private View createLineStackedView() { // Categories XYMultipleSeriesDataset tmp_dataset = new XYMultipleSeriesDataset(); String[] labels = this.sensor.getLabels().split(";"); int nb_values = 0; try { nb_values = this.sensor.getMeasures().get(0).getValue().split(";").length; } catch (IndexOutOfBoundsException ioobe) { return this.createTextView(); } for (int i = 0; i < nb_values; i++) { TimeSeries timeSerie = new TimeSeries(labels[i]); for (int j = 0; j < this.sensor.getMeasures().size(); j++) { Date date = this.sensor.getMeasures().get(j).getTimestamp(); Double value = 0.0; for (int k = 0; k <= i; k++) { Double old_value = new Double(this.sensor.getMeasures().get(j).getValue().split(";")[k]); value += old_value; } timeSerie.add(date, value); } tmp_dataset.addSeries(timeSerie); } XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); for (int i = tmp_dataset.getSeries().length - 1; i >= 0; i--) { dataset.addSeries(tmp_dataset.getSeriesAt(i)); } // Renderer XYMultipleSeriesRenderer renderer = this.getDefaultRenderer(); for (int i = Arrays.copyOfRange(this.colors, 0, nb_values).length - 1; i >= 0; i--) { int color = Arrays.copyOfRange(this.colors, 0, nb_values)[i]; XYSeriesRenderer r = new XYSeriesRenderer(); r.setColor(color); r.setFillBelowLineColor(color); r.setFillBelowLine(true); r.setLineWidth(2); renderer.addSeriesRenderer(r); } renderer.setShowLegend(true); renderer.setPanEnabled(false, false); renderer.setZoomEnabled(false, false); renderer.setGridColor(this.lightFontColor); renderer.setMarginsColor(this.backgroundColor); renderer.setXLabelsColor(this.fontColor); renderer.setYLabelsColor(0, this.fontColor); renderer.setYLabelsAlign(Align.RIGHT); renderer.setYAxisMin(0); renderer.setXLabels(0); int count = dataset.getSeriesAt(0).getItemCount(); String dateFormat = "HH:mm\nMMM dd"; if (this.period.equals("hour")) { dateFormat = "HH:mm"; } for (int i = 0; i < count; i = i + (count / 5)) { Double d = dataset.getSeriesAt(0).getX(i); Date date = this.sensor.getMeasures().get(i).getTimestamp(); String s = new SimpleDateFormat(dateFormat).format(date); renderer.addXTextLabel(d, s); } this.setYAxisValues(dataset, renderer); renderer.setBarSpacing(0); return ChartFactory.getLineChartView(this.context, dataset, renderer); } private View createBarView() { // Categories XYMultipleSeriesDataset tmp_dataset = new XYMultipleSeriesDataset(); String[] labels = this.sensor.getLabels().split(";"); int nb_values = 0; try { nb_values = this.sensor.getMeasures().get(0).getValue().split(";").length; } catch (IndexOutOfBoundsException ioobe) { return this.createTextView(); } for (int i = 0; i < nb_values; i++) { TimeSeries timeSerie = new TimeSeries(labels[i]); for (int j = 0; j < this.sensor.getMeasures().size(); j++) { Date date = this.sensor.getMeasures().get(j).getTimestamp(); Double value = 0.0; for (int k = 0; k <= i; k++) { Double old_value = new Double(this.sensor.getMeasures().get(j).getValue().split(";")[k]); value += old_value; } timeSerie.add(date, value); } tmp_dataset.addSeries(timeSerie); } XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); for (int i = tmp_dataset.getSeries().length - 1; i >= 0; i--) { dataset.addSeries(tmp_dataset.getSeriesAt(i)); } // Renderer XYMultipleSeriesRenderer renderer = this.getDefaultRenderer(); for (int i = Arrays.copyOfRange(this.colors, 0, nb_values).length - 1; i >= 0; i--) { int color = Arrays.copyOfRange(this.colors, 0, nb_values)[i]; XYSeriesRenderer r = new XYSeriesRenderer(); r.setColor(color); renderer.addSeriesRenderer(r); } renderer.setShowLegend(true); renderer.setPanEnabled(false, false); renderer.setZoomEnabled(false, false); renderer.setGridColor(this.lightFontColor); renderer.setMarginsColor(this.backgroundColor); renderer.setXLabelsColor(this.fontColor); renderer.setYLabelsColor(0, this.fontColor); renderer.setYLabelsAlign(Align.RIGHT); renderer.setYAxisMin(0); renderer.setXLabels(0); int count = dataset.getSeriesAt(0).getItemCount(); String dateFormat = "HH:mm\nMMM dd"; if (this.period.equals("hour")) { dateFormat = "HH:mm"; } for (int i = 0; i < count; i = i + (count / 5)) { Double d = dataset.getSeriesAt(0).getX(i); Date date = this.sensor.getMeasures().get(i).getTimestamp(); String s = new SimpleDateFormat(dateFormat).format(date); renderer.addXTextLabel(d, s); } this.setYAxisValues(dataset, renderer); renderer.setBarSpacing(0); return ChartFactory.getBarChartView(this.context, dataset, renderer, Type.STACKED); } private View createBarGroupView() { // Categories XYMultipleSeriesDataset tmp_dataset = new XYMultipleSeriesDataset(); String[] labels = this.sensor.getLabels().split(";"); int nb_values = 0; try { nb_values = this.sensor.getMeasures().get(0).getValue().split(";").length; } catch (IndexOutOfBoundsException ioobe) { return this.createTextView(); } for (int i = 0; i < nb_values; i++) { TimeSeries timeSerie = new TimeSeries(labels[i]); for (int j = 0; j < this.sensor.getMeasures().size(); j++) { Date date = this.sensor.getMeasures().get(j).getTimestamp(); Double value = new Double(this.sensor.getMeasures().get(j).getValue().split(";")[i]); timeSerie.add(date, value); } tmp_dataset.addSeries(timeSerie); } XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset(); for (int i = tmp_dataset.getSeries().length - 1; i >= 0; i--) { dataset.addSeries(tmp_dataset.getSeriesAt(i)); } // Renderer XYMultipleSeriesRenderer renderer = this.getDefaultRenderer(); for (int i = Arrays.copyOfRange(this.colors, 0, nb_values).length - 1; i >= 0; i--) { int color = Arrays.copyOfRange(this.colors, 0, nb_values)[i]; XYSeriesRenderer r = new XYSeriesRenderer(); r.setColor(color); renderer.addSeriesRenderer(r); } renderer.setShowLegend(true); renderer.setPanEnabled(false, false); renderer.setZoomEnabled(false, false); renderer.setGridColor(this.lightFontColor); renderer.setMarginsColor(this.backgroundColor); renderer.setXLabelsColor(this.fontColor); renderer.setYLabelsColor(0, this.fontColor); renderer.setYLabelsAlign(Align.RIGHT); renderer.setYAxisMin(0); renderer.setXLabels(0); int count = dataset.getSeriesAt(0).getItemCount(); String dateFormat = "HH:mm\nMMM dd"; if (this.period.equals("hour")) { dateFormat = "HH:mm"; } for (int i = 0; i < count; i = i + (count / 5)) { Double d = dataset.getSeriesAt(0).getX(i); Date date = this.sensor.getMeasures().get(i).getTimestamp(); String s = new SimpleDateFormat(dateFormat).format(date); renderer.addXTextLabel(d, s); } this.setYAxisValues(dataset, renderer); renderer.setBarSpacing(0.2); return ChartFactory.getBarChartView(this.context, dataset, renderer, Type.DEFAULT); } @SuppressWarnings("deprecation") private View createTextView() { final TextView tv = new TextView(this.context); String str = "No data found for this sensor. Server is maybe unavailable."; try { str = this.sensor.getMeasures().get(0).getValue(); } catch (IndexOutOfBoundsException ioobe) { } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT); tv.setLayoutParams(params); tv.setPadding(10, 10, 10, 10); tv.setBackgroundColor(Color.parseColor("#303030")); tv.setTextColor(Color.parseColor("#7FAE00")); tv.setTypeface(Typeface.MONOSPACE, Typeface.BOLD); tv.setText(str); tv.setTextSize(15); return tv; } private void setYAxisValues(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer) { renderer.setYLabels(0); Double maxd = 0.0d; for (int i = 0; i < dataset.getSeriesCount(); i++) { if (dataset.getSeriesAt(i).getMaxY() > maxd) { maxd = dataset.getSeriesAt(i).getMaxY(); } } DecimalFormat formatter = new DecimalFormat(".00"); for (double i = 0; i < maxd; i = i + (maxd / 3)) { renderer.addYTextLabel(i, formatter.format(i) + " " + this.sensor.getUnit() + " "); } renderer.addYTextLabel(maxd * 0.99, formatter.format(maxd) + " " + this.sensor.getUnit() + " "); } }